package com.mamingchao.basics.designpattern.flyweight;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 结合tank的项目场景，屏幕内共用500个子弹
 * 如果子弹射出了屏幕，就把字段living 标志设置为 false，然后子弹再回子弹池子里
 * 如果有坦克再射出子弹，再从池子里 拿 living为false的对象，重新修改它的position，就可以里
 *
 * 下面的代码模拟这个场景
 * Created by mamingchao on 2020/10/15.
 */
public class FlyweighTester {
    public static void main(String[] args) {
        //init bullet pool
        BulletPool pool = new BulletPool();
        for (int i = 0; i <500 ; i++) {
            pool.addBullet(new Bullet("bullet--" + i));
        }

        //创建10个坦克
        for (int i = 0; i <10 ; i++) {
            new Thread(()->{
                new Tank().shoot(pool.getBullet());
            }).start();
        }
    }
}

class Tank{
    void shoot(Bullet bullet){
        bullet.living = true;
        System.out.println("The tank has shooted " + bullet.bulletName);

        try {
            TimeUnit.SECONDS.sleep(1);
            bullet.living = false;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Bullet{
    Bullet(String bulletName){
        this.bulletName = bulletName;
    }
    boolean living = false;
    String bulletName;
}

class BulletPool{
    List<Bullet> bullets = new ArrayList<>();
    ReentrantLock lock = new ReentrantLock();

    void addBullet(Bullet bullet){
        this.bullets.add(bullet);
    }

    synchronized Bullet getBullet(){
        for (Bullet bullet:bullets) {
            if (!bullet.living)
                return bullet;
        }
        return null;
    }
}